
import pygame
import sys
import random

# 初始化pygame
pygame.init()

# 屏幕设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("仓颉造字 - 汉字拼图游戏")

# 颜色定义
BACKGROUND = (240, 235, 220)
TEXT_COLOR = (50, 50, 50)
BUTTON_COLOR = (180, 160, 120)
BUTTON_HOVER = (200, 180, 140)
GRID_COLOR = (200, 190, 170)
CORRECT_COLOR = (120, 180, 120)
HINT_COLOR = (255, 220, 120)

# 汉字和它们的部件
hanzi_parts = {
    "明": ["日", "月"],
    "林": ["木", "木"],
    "森": ["木", "木", "木"],
    "好": ["女", "子"],
    "休": ["亻", "木"]
}

# 游戏状态
current_hanzi = "明"
current_parts = hanzi_parts[current_hanzi].copy()
random.shuffle(current_parts)
selected_part = None
score = 0
level = 1
game_completed = False
show_hint = False
hint_timer = 0

# 字体
font_large = pygame.font.SysFont('simhei', 80)
font_medium = pygame.font.SysFont('simhei', 40)
font_small = pygame.font.SysFont('simhei', 30)

# 按钮类
class Button:
    def __init__(self, x, y, width, height, text):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.is_hovered = False
        
    def draw(self, screen):
        color = BUTTON_HOVER if self.is_hovered else BUTTON_COLOR
        pygame.draw.rect(screen, color, self.rect, border_radius=10)
        pygame.draw.rect(screen, TEXT_COLOR, self.rect, 2, border_radius=10)
        
        text_surface = font_small.render(self.text, True, TEXT_COLOR)
        text_rect = text_surface.get_rect(center=self.rect.center)
        screen.blit(text_surface, text_rect)
        
    def check_hover(self, pos):
        self.is_hovered = self.rect.collidepoint(pos)
        return self.is_hovered
        
    def is_clicked(self, pos):
        return self.rect.collidepoint(pos)

# 汉字部件类
class HanziPart:
    def __init__(self, text, x, y):
        self.text = text
        self.x = x
        self.y = y
        self.original_x = x
        self.original_y = y
        self.is_dragging = False
        self.is_placed = False
        self.target_x = 0
        self.target_y = 0
        
    def draw(self, screen):
        if not self.is_placed:
            # 绘制部件背景
            rect = pygame.Rect(self.x - 30, self.y - 30, 60, 60)
            pygame.draw.rect(screen, BUTTON_COLOR, rect, border_radius=8)
            pygame.draw.rect(screen, TEXT_COLOR, rect, 2, border_radius=8)
            
            # 绘制部件文字
            text_surface = font_medium.render(self.text, True, TEXT_COLOR)
            text_rect = text_surface.get_rect(center=(self.x, self.y))
            screen.blit(text_surface, text_rect)
        
    def update_position(self, mouse_x, mouse_y):
        if self.is_dragging and not self.is_placed:
            self.x = mouse_x
            self.y = mouse_y
            
    def check_placement(self, target_areas):
        for i, area in enumerate(target_areas):
            if area['rect'].collidepoint(self.x, self.y):
                if area['expected'] == self.text and not area['occupied']:
                    # 正确放置
                    self.x = area['rect'].centerx
                    self.y = area['rect'].centery
                    self.is_placed = True
                    area['occupied'] = True
                    return True, i
                else:
                    # 错误放置，回到原位
                    self.x = self.original_x
                    self.y = self.original_y
                    return False, -1
        return None, -1

# 创建按钮
hint_button = Button(50, 500, 120, 50, "提示")
restart_button = Button(200, 500, 120, 50, "重新开始")
next_button = Button(350, 500, 120, 50, "下一关")

# 创建汉字部件
def create_parts():
    parts = []
    start_x = 100
    start_y = 150
    for i, part in enumerate(current_parts):
        x = start_x + (i % 3) * 100
        y = start_y + (i // 3) * 100
        parts.append(HanziPart(part, x, y))
    return parts

# 创建目标区域
def create_target_areas():
    areas = []
    center_x = WIDTH // 2
    center_y = HEIGHT // 2 - 50
    
    if current_hanzi == "明":
        areas = [
            {'rect': pygame.Rect(center_x - 60, center_y - 40, 80, 80), 'expected': '日', 'occupied': False},
            {'rect': pygame.Rect(center_x + 20, center_y - 40, 80, 80), 'expected': '月', 'occupied': False}
        ]
    elif current_hanzi == "林":
        areas = [
            {'rect': pygame.Rect(center_x - 80, center_y - 40, 80, 80), 'expected': '木', 'occupied': False},
            {'rect': pygame.Rect(center_x + 10, center_y - 40, 80, 80), 'expected': '木', 'occupied': False}
        ]
    elif current_hanzi == "森":
        areas = [
            {'rect': pygame.Rect(center_x - 80, center_y - 80, 80, 80), 'expected': '木', 'occupied': False},
            {'rect': pygame.Rect(center_x + 10, center_y - 80, 80, 80), 'expected': '木', 'occupied': False},
            {'rect': pygame.Rect(center_x - 35, center_y + 20, 80, 80), 'expected': '木', 'occupied': False}
        ]
    elif current_hanzi == "好":
        areas = [
            {'rect': pygame.Rect(center_x - 80, center_y - 40, 80, 80), 'expected': '女', 'occupied': False},
            {'rect': pygame.Rect(center_x + 10, center_y - 40, 80, 80), 'expected': '子', 'occupied': False}
        ]
    elif current_hanzi == "休":
        areas = [
            {'rect': pygame.Rect(center_x - 80, center_y - 40, 80, 80), 'expected': '亻', 'occupied': False},
            {'rect': pygame.Rect(center_x + 10, center_y - 40, 80, 80), 'expected': '木', 'occupied': False}
        ]
    
    return areas

# 检查游戏完成
def check_completion(parts, target_areas):
    placed_count = sum(1 for part in parts if part.is_placed)
    return placed_count == len(target_areas)

# 下一关
def next_level():
    global current_hanzi, current_parts, parts, target_areas, game_completed, level, score, show_hint, hint_timer
    
    hanzi_list = list(hanzi_parts.keys())
    current_index = hanzi_list.index(current_hanzi)
    next_index = (current_index + 1) % len(hanzi_list)
    
    current_hanzi = hanzi_list[next_index]
    current_parts = hanzi_parts[current_hanzi].copy()
    random.shuffle(current_parts)
    
    parts = create_parts()
    target_areas = create_target_areas()
    game_completed = False
    level += 1
    score += 100
    show_hint = False
    hint_timer = 0

# 重新开始当前关
def restart_level():
    global parts, target_areas, game_completed, show_hint, hint_timer
    
    for part in parts:
        part.x = part.original_x
        part.y = part.original_y
        part.is_placed = False
        part.is_dragging = False
    
    target_areas = create_target_areas()
    game_completed = False
    show_hint = False
    hint_timer = 0

# 显示提示
def show_hint_func():
    global show_hint, hint_timer
    show_hint = True
    hint_timer = 180  # 3秒 (60 FPS)

# 初始化游戏
parts = create_parts()
target_areas = create_target_areas()

# 游戏主循环
clock = pygame.time.Clock()
running = True

while running:
    dt = clock.tick(60)
    mouse_pos = pygame.mouse.get_pos()
    
    # 事件处理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  # 左键
                # 检查按钮点击
                if hint_button.is_clicked(mouse_pos):
                    show_hint_func()
                elif restart_button.is_clicked(mouse_pos):
                    restart_level()
                elif next_button.is_clicked(mouse_pos) and game_completed:
                    next_level()
                
                # 检查部件拖拽
                if not game_completed:
                    for part in parts:
                        if not part.is_placed:
                            rect = pygame.Rect(part.x - 30, part.y - 30, 60, 60)
                            if rect.collidepoint(mouse_pos):
                                part.is_dragging = True
                                selected_part = part
                                break
                                
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1 and selected_part:
                # 检查放置
                success, area_index = selected_part.check_placement(target_areas)
                if success is False:
                    # 放置错误，扣分
                    score = max(0, score - 10)
                elif success is True:
                    # 放置正确，加分
                    score += 20
                    # 检查游戏完成
                    if check_completion(parts, target_areas):
                        game_completed = True
                        score += 50
                        
                selected_part.is_dragging = False
                selected_part = None
                
        elif event.type == pygame.MOUSEMOTION:
            # 更新拖拽中的部件位置
            if selected_part:
                selected_part.update_position(mouse_pos[0], mouse_pos[1])
    
    # 更新提示计时器
    if show_hint:
        hint_timer -= 1
        if hint_timer <= 0:
            show_hint = False
    
    # 更新按钮悬停状态
    hint_button.check_hover(mouse_pos)
    restart_button.check_hover(mouse_pos)
    next_button.check_hover(mouse_pos)
    
    # 绘制
    screen.fill(BACKGROUND)
    
    # 绘制标题
    title_text = font_large.render("仓颉造字", True, TEXT_COLOR)
    title_rect = title_text.get_rect(center=(WIDTH // 2, 60))
    screen.blit(title_text, title_rect)
    
    # 绘制目标汉字（半透明背景）
    if not game_completed:
        target_text = font_large.render(current_hanzi, True, (200, 200, 200))
        target_rect = target_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 - 50))
        screen.blit(target_text, target_rect)
    
    # 绘制目标区域
    for area in target_areas:
        color = HINT_COLOR if show_hint and not area['occupied'] else GRID_COLOR
        if area['occupied']:
            color = CORRECT_COLOR
        pygame.draw.rect(screen, color, area['rect'], 3, border_radius=8)
        
        # 显示期望的部件
        if not area['occupied']:
            hint_text = font_small.render(area['expected'], True, (150, 150, 150))
            hint_rect = hint_text.get_rect(center=area['rect'].center)
            screen.blit(hint_text, hint_rect)
    
    # 绘制汉字部件
    for part in parts:
        part.draw(screen)
    
    # 绘制按钮
    hint_button.draw(screen)
    restart_button.draw(screen)
    if game_completed:
        next_button.draw(screen)
    
    # 绘制分数和关卡信息
    score_text = font_small.render(f"分数: {score}", True, TEXT_COLOR)
    level_text = font_small.render(f"关卡: {level}", True, TEXT_COLOR)
    screen.blit(score_text, (WIDTH - 150, 20))
    screen.blit(level_text, (WIDTH - 150, 60))
    
    # 绘制完成提示
    if game_completed:
        complete_text = font_medium.render("恭喜完成!", True, (0, 120, 0))
        complete_rect = complete_text.get_rect(center=(WIDTH // 2, HEIGHT - 100))
        screen.blit(complete_text, complete_rect)
    
    pygame.display.flip()

pygame.quit()
sys.exit()
